/*
 * 代号：凤凰
 * http://www.jphenix.org
 * 2014年12月11日
 * V4.0
 */
package com.jphenix.service.communicate.pipe;

import com.jphenix.servlet.parent.ServiceBeanParent;
import com.jphenix.standard.docs.BeanInfo;
import com.jphenix.standard.docs.ClassInfo;
import com.jphenix.standard.docs.Running;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * Socket监听转发服务
 * 
 * 2019-01-24 修改了父类的类路径
 * 2020-09-12 去掉了提醒注释
 * 2024-06-08 修改了警告代码
 * 
 * @author 马宝刚
 * 2014年12月11日
 */
@ClassInfo({"2024-06-08 11:33","Socket监听转发服务"})
@BeanInfo({"socketpipeservice"})
@Running({"1","start","","stop"})
public class SocketPipeService extends ServiceBeanParent {

    private String remoteHost = ""; //远程地址
    private int remotePort = 0;       //远程端口
    private int localPort = 0;           //本地监听端口
    
    //private boolean outBuffer = false; //是否输出到缓存
   // private SFastBuffer buffer = new SFastBuffer(); //快速缓存
    private ServerSocket socket = null; //监听类
    //private ListenAcceptThread lat = null; //监听响应线程
    private SocketPipe sp = null; //管道对接类
    
    /**
     * 连接对象
     * @author 马宝刚
     * 2014年12月12日
     */
    protected class PipeConnection {
        
        private Socket conn = null; //连接对象
        
        /**
         * 构造函数
         * @author 马宝刚
         */
        public PipeConnection(Socket socket) {
            super();
            conn = socket;
            execute(); //执行对接
        }
        
        /**
         * 执行执行对接
         * 
         * 2014年12月12日
         * @author 马宝刚
         */
        public void execute() {
            Socket remoteSocket = null; //目标端口
            try {
                remoteSocket = new Socket(remoteHost,remotePort);
            }catch(Exception e) {
                error("Link Remote Host Exception host:["+remoteHost+"] port:["+remotePort+"]",e);
                e.printStackTrace();
                return;
            }finally {
            	if(remoteSocket!=null) {
            		try {
            			remoteSocket.close();
            		}catch(Exception e2) {}
            	}
            }
            log("Link Remote Host Completed host:["+remoteHost+"] port:["+remotePort+"]");
            
            sp = new SocketPipe(conn,remoteSocket);
            try {
                sp.start();
            }catch(Exception e) {
                e.printStackTrace();
                error("Create Connection Exception LocalPort:["+localPort+"] RemoteHost:["+remoteHost+"] RemotePort:["+remotePort+"]",e);
            }
        }
    }
    
    /**
     * 执行监听线程
     * @author 刘虻
     * 2008-7-8下午04:06:28
     */
    protected class ListenAcceptThread extends Thread {
        
        protected ServerSocket sSocket = null; //服务器Socket
        
        /**
         * 构造函数
         * 2008-7-8下午04:06:50
         */
        public ListenAcceptThread() {
            super("Serv-ListenAcceptThread");
        }
        
        /**
         * 覆盖方法
         * @author 刘虻
         * 2008-7-8下午04:06:59
         */
        @Override
        public void run() {
            try {
                while (true) {
                    try {
                        //获取浏览器与服务器连接Socket
                        Socket socket = sSocket.accept();
                        new PipeConnection(socket);
                    } catch (IOException e) {
                        log("Accept: " + e);
                    } catch (SecurityException se) {
                        log("Illegal access: " + se);
                    }
                }
            } catch (Throwable t) {
                return;
            } finally {
                try {
                    if (sSocket != null) {
                        sSocket.close();
                    }
                } catch (IOException e) {
                }
            }
        }
    }
    
    /**
     * 构造函数
     * @author 马宝刚
     */
    public SocketPipeService() {
        super();
    }
    
    /**
     * 构造函数
     * @author 马宝刚
     */
    public SocketPipeService(int localPort,String remoteHost,int remotePort) {
        super();
        this.localPort = localPort;
        this.remoteHost = remoteHost;
        this.remotePort = remotePort;
    }
    
    /**
     * 终止服务
     * 2014年12月11日
     * @author 马宝刚
     */
    public void stop() {
        //待处理
    }
    
    /**
     * 启动服务
     * @throws Exception 异常
     * 2014年12月11日
     * @author 马宝刚
     */
    public void start() throws Exception {
        if(localPort<1 || remotePort<1 || remoteHost==null || remoteHost.length()<1) {
            log.startLog("[Warning] The Parameter is Empty LocalPort:["+localPort+"] RemotePort:["
                            +remotePort+"] RemoteHost:["+remoteHost+"]");
            return;
        }
        try {
            socket = new ServerSocket(localPort,0);
        }catch(Exception e) {
            e.printStackTrace();
            log.startLog("[Error] ***************** Listen Port:["+localPort+"] Exception:"+e);
        }
        //连接后的本机地址
        String hostName = socket.getInetAddress().getHostName();
        log.log("Start Listening ["+hostName+"]");
        
        //lat = new ListenAcceptThread();
    }
    
    /**
     * 获取本地监听端口
     * @return 本地监听端口
     * 2014年12月11日
     * @author 马宝刚
     */
    public int getLocalPort() {
        return localPort;
    }
    
    /**
     * 设置本地监听端口
     * @param localPort 本地监听端口
     * 2014年12月11日
     * @author 马宝刚
     */
    public void setLocalPort(int localPort) {
        this.localPort = localPort;
    }

    /**
     * 获取远程端口
     * @return 远程端口
     * 2014年12月11日
     * @author 马宝刚
     */
    public int getRemotePort() {
        return remotePort;
    }
    
    /**
     * 设置远程端口
     * @param remotePort 远程端口
     * 2014年12月11日
     * @author 马宝刚
     */
    public void setRemotePort(int remotePort) {
        this.remotePort = remotePort;
    }
    
    /**
     * 获取远程地址
     * @return 远程地址
     * 2014年12月11日
     * @author 马宝刚
     */
    public String getRemoteHost() {
        if(remoteHost==null) {
            remoteHost = "";
        }
        return remoteHost;
    }
    
    /**
     * 设置远程地址
     * @param remoteHost 远程地址
     * 2014年12月11日
     * @author 马宝刚
     */
    public void setRemoteHost(String remoteHost) {
        this.remoteHost = remoteHost;
    }
}
